home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- ***
- *** CDTV Audio Examples by Carl Sassenrath (10-Dec-90)
- ***
- *** Copyright (C) 1990 Commodore International, Ltd.
- *** Permission granted to use for your CDTV programs.
- ***
- ************************************************************************
- ***
- *** This file contains examples of how to perform a few simple
- *** CD Audio commands on CDTV. It was cranked out in a few
- *** hours to help illustrate a few effects... and it all seems
- *** to work (could use a little tweaking maybe). Sorry, but I have
- *** not had the chance to convert it from Manx C to Lattice C, so
- *** if you do, please send me a copy. If not, I will get too it
- *** RSN... -Carl-
- ***
- *** Send comments, problems, etc. to:
- *** Sassenrath, P.O. Box 1510, Ukiah, CA 95482
- *** Phone: (707) 462-4878 FAX: (707) 462-4879
- *** CBM VAX: carl
- ***
- ***********************************************************************/
-
- #include <exec/types.h>
- #include <exec/io.h>
- #include <devices/cdtv.h>
-
- extern struct IOStdReq *CreateStdIO();
- extern struct MsgPort *CreatePort();
- struct IOStdReq *IOReq1 = NULL;
- struct IOStdReq *IOReq2 = NULL;
- struct MsgPort *IOPort = NULL;
-
- int Track;
- struct CDTOC Toc[100];
- char Buffer[10*2048];
-
- char AssertFail[] = "Assertion failed (MUST)";
-
- #define MUST(expr) if (!(expr)) Quit(AssertFail);
-
-
- /***********************************************************************
- ***
- *** Main
- ***
- ***********************************************************************/
- main(argc,argv)
- int argc;
- char *argv[];
- {
- printf("CDTV Audio Example (10-Dec-90)\n");
-
- Init();
-
- ReadTOC(); /* Read CD table of contents */
-
- DoIOR(IOReq1,CD_MUTE,0x7fff,1,0); /* Set to full volume */
-
- Play();
- PlayBurst();
- PlayBounce();
- PlayFastFwd();
- PlayAltFastFwd();
- PlayShow();
- PlayAbort();
- PlayFade();
- PlayMixedMode();
-
- Quit(0);
- }
-
- /***********************************************************************
- ***
- *** Init -- initialize program and structures
- ***
- ***********************************************************************/
- Init()
- {
- MUST(IOPort = CreatePort(0,0));
- MUST(IOReq1 = CreateStdIO(IOPort));
- MUST(IOReq2 = CreateStdIO(IOPort));
-
- if (OpenDevice("cdtv.device",0,IOReq1,0))
- Quit("CDTV Device will not open");
-
- *IOReq2 = *IOReq1; /* Note: structure copy */
- }
-
- /***********************************************************************
- ***
- *** Quit -- exit program and clean-up. Return an error in needed.
- ***
- ***********************************************************************/
- Quit(s)
- char *s; /* error message */
- {
- if (IOReq1->io_Device) CloseDevice(IOReq1);
- if (IOReq1) DeleteStdIO(IOReq1);
- if (IOReq2) DeleteStdIO(IOReq2);
- if (IOPort) DeletePort(IOPort);
- if (s) {printf("\nERROR: %s\n",s); exit(40);}
- else exit(0);
- }
-
- /***********************************************************************
- ***
- *** DoIOR -- execute a device command
- ***
- ***********************************************************************/
- DoIOR(req,cmd,off,len,data)
- struct IOStdReq *req;
- int cmd;
- long off;
- long len;
- APTR data;
- {
- req->io_Command = cmd;
- req->io_Offset = off;
- req->io_Length = len;
- req->io_Data = data;
- if (DoIO(req)) Quit("DoIO command error");
- }
-
- /***********************************************************************
- ***
- *** SendIOR -- asynchronously execute a device command
- ***
- ***********************************************************************/
- SendIOR(req,cmd,off,len,data)
- struct IOStdReq *req;
- int cmd;
- long off;
- long len;
- APTR data;
- {
- req->io_Command = cmd;
- req->io_Offset = off;
- req->io_Length = len;
- req->io_Data = data;
- SendIO(req);
- }
-
- /***********************************************************************
- ***
- *** AddMSF -- add two Min:Sec:Frm values
- ***
- ***********************************************************************/
- CDPOS AddMSF(arg1,arg2)
- CDPOS arg1, arg2;
- {
- arg1.MSF.Frame += arg2.MSF.Frame;
- if (arg1.MSF.Frame >= 75) {arg1.MSF.Frame -= 75; arg1.MSF.Second++;}
-
- arg1.MSF.Second += arg2.MSF.Second;
- if (arg1.MSF.Second >= 60) {arg1.MSF.Second -= 60; arg1.MSF.Minute++;}
-
- arg1.MSF.Minute += arg2.MSF.Minute;
-
- return arg1;
- }
-
- /***********************************************************************
- ***
- *** ReadTOC -- read entire CD table of contents
- ***
- ***********************************************************************/
- ReadTOC()
- {
- DoIOR(IOReq1,CD_TOCMSF,0,100,&Toc[0]);
-
- printf("CD is %02d:%02d:%02d long ",
- Toc[0].Position.MSF.Minute,
- Toc[0].Position.MSF.Second,
- Toc[0].Position.MSF.Frame);
- printf("with tracks %d to %d\n",Toc[0].Track,Toc[0].LastTrack);
-
- DoIOR(IOReq1,CD_ISROM,0,0,0);
- printf("It %s CD-ROM data\n",
- IOReq1->io_Actual ? "has" : "does not have");
-
- if (IOReq1->io_Actual && Toc[0].LastTrack <= 1)
- Quit("No audio tracks\n");
-
- if (Toc[0].LastTrack <= 2) Quit("Not enough tracks\n");
- Track = ((Toc[0].LastTrack >= 6) ? 6 : 2);
- }
-
- /***********************************************************************
- ***
- *** Example Functions
- ***
- ***********************************************************************/
- Play()
- {
- printf("Play 20 seconds of track %d...\n",Track);
- DoIOR(IOReq1,CD_PLAYMSF,Toc[Track].Position.Raw,
- AddMSF(Toc[Track].Position.Raw,TOMSF(0,20,0)).Raw,0);
- }
-
- PlayBurst()
- {
- int i;
- CDPOS start, stop;
-
- printf("Play 20 short sequential bursts...\n");
- start.Raw = Toc[Track].Position.Raw;
-
- for (i = 0; i < 40; i++)
- {
- stop.Raw = AddMSF(start.Raw,TOMSF(0,0,19));
- DoIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
- start.Raw = stop.Raw;
- }
- }
-
- PlayBounce()
- {
- int i;
- CDPOS start, stop;
-
- printf("Bounce the 'needle' on the 'record'...\n");
- start.Raw = AddMSF(Toc[Track].Position.Raw,TOMSF(0,6,0));
- stop.Raw = AddMSF(start.Raw,TOMSF(0,0,6));
-
- for (i = 0; i < 30; i++)
- {
- DoIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
- }
- }
-
- PlayFastFwd()
- {
- int i;
- CDPOS start, stop;
-
- printf("Play fast forward...\n");
- start.Raw = Toc[Track].Position.Raw;
-
- for (i = 0; i < 40; i++)
- {
- stop.Raw = AddMSF(start.Raw,TOMSF(0,0,19));
- DoIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
- start.Raw = AddMSF(start.Raw,TOMSF(0,1,0));
- }
- }
-
- PlayAltFastFwd() /* Note: requires 2 I/O requests! */
- {
- int i;
- CDPOS start, stop;
-
- printf("Play alternate fast forward...\n");
- start.Raw = Toc[Track].Position.Raw;
- stop.Raw = AddMSF(start.Raw,TOMSF(0,40,0));
- SendIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
-
- for (i = 0; i < 30; i++)
- {
- Delay(50/5); /* Note: Delay() not too accurate */
- start.Raw = AddMSF(start.Raw,TOMSF(0,0,30));
- DoIOR(IOReq2,CD_POKEPLAYMSF,start.Raw,stop.Raw,0);
- }
-
- AbortIO(IOReq1);
- WaitIO(IOReq1);
- }
-
- PlayShow()
- {
- CDPOS start, stop;
- struct CDSubQ subq;
-
- printf("Play and show track time...\n");
- start.Raw = Toc[Track].Position.Raw;
- stop.Raw = AddMSF(start.Raw,TOMSF(0,20,0));
- SendIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
-
- while (!CheckIO(IOReq1))
- {
- DoIOR(IOReq2,CD_SUBQMSF,0,0,&subq);
- if (subq.Status == SQSTAT_PLAYING)
- {
- printf("%02d:%02d:%02d\n",
- subq.TrackPosition.MSF.Minute,
- subq.TrackPosition.MSF.Second,
- subq.TrackPosition.MSF.Frame);
- }
- }
-
- WaitIO(IOReq1);
- }
-
- PlayAbort()
- {
- printf("Play 20 sec, abort after 10...\n");
-
- SendIOR(IOReq1,CD_PLAYMSF,Toc[Track].Position.Raw,
- AddMSF(Toc[Track].Position.Raw,TOMSF(0,20,0)).Raw,0);
-
- Delay(50*10);
- AbortIO(IOReq1);
- WaitIO(IOReq1);
- DoIOR(IOReq1,CD_STOPPLAY,0,0,0); /* only if you want to */
- }
-
- PlayFade()
- {
- CDPOS start, stop;
- int i;
-
- printf("Play while fading up and down...\n");
-
- start.Raw = AddMSF(Toc[Track].Position.Raw,TOMSF(1,0,0));
- stop.Raw = AddMSF(start.Raw,TOMSF(1,0,0));
- SendIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
-
- DoIOR(IOReq2,CD_FADE,0x7fff,0,0); /* full volume */
-
- for (i = 0; i < 5; i++)
- {
- DoIOR(IOReq2,CD_FADE,0,150,0);
- Delay(100);
- DoIOR(IOReq2,CD_FADE,0x7fff,150,0);
- Delay(100);
- }
-
- for (i = 0; i < 10; i++)
- {
- DoIOR(IOReq2,CD_FADE,0,15,0);
- Delay(50/4);
- DoIOR(IOReq2,CD_FADE,0x7fff,15,0);
- Delay(50/4);
- }
-
- DoIOR(IOReq2,CD_FADE,0,750,0);
- Delay(50*10);
-
- AbortIO(IOReq1);
- WaitIO(IOReq1);
-
- DoIOR(IOReq1,CD_STOPPLAY,0,0,0); /* stop the play for good */
- DoIOR(IOReq2,CD_FADE,0x7fff,0,0); /* return to full vol */
- }
-
- PlayMixedMode()
- {
- int i;
- CDPOS start, stop;
-
- printf("Read and Play a mixed mode disk...\n");
-
- DoIOR(IOReq1,CD_ISROM,0,0,0);
- if (!IOReq1->io_Actual)
- {
- printf("Not a mixed mode disk!\n");
- return;
- }
-
- start.Raw = Toc[Track].Position.Raw;
-
- for (i = 0; i < 40; i++)
- {
- printf("Reading...\n");
- DoIOR(IOReq1,CD_READ,i*10*2048,6*2048,Buffer);
- if (i==0) printf("Whoops... will fix that glitch\n");
- stop.Raw = AddMSF(start.Raw,TOMSF(0,1,0));
- printf("Playing...\n");
- DoIOR(IOReq1,CD_PLAYMSF,start.Raw,stop.Raw,0);
- start.Raw = stop.Raw;
- }
- }
-